/**
 * @file dialpad.c
 *
 */

/*********************
 *      INCLUDES
 *********************/
#include <stdio.h>
#include "lv_watch.h"

#if USE_LV_WATCH_DIALPAD

/*********************
 *      DEFINES
 *********************/
#define DIAL_PAD_TA_W    (LV_HOR_RES - 30)
#define DIAL_PAD_TA_H    35
#define DIAL_PAD_X_NUM  3
#define DIAL_PAD_Y_NUM  4
#define DIAL_PAD_NUM  (DIAL_PAD_X_NUM * DIAL_PAD_Y_NUM)
#define DIAL_PAD_CONT_W  DIAL_PAD_TA_W
#define DIAL_PAD_CONT_H  (LV_VER_RES - DIAL_PAD_TA_H - 25)

#define DIAL_PAD_TEST  0    //for test code

/**********************
 *  STATIC PROTOTYPES
 **********************/
static void dialpad_prepare_destory(lv_obj_t * activity_obj);
static lv_dialpad_obj_ext_t * dialpad_get_ext(void);
static void dialpad_note_create(lv_obj_t * obj);
static void dialpad_btn_event_cb(lv_obj_t * btn, lv_event_t e);
static lv_res_t dialpad_btn_press_action(lv_obj_t * btn);
static lv_res_t dialpad_btn_long_press_action(lv_obj_t * btn);
static lv_res_t dialpad_btn_short_click_action(lv_obj_t * btn);

/**********************
 *   GLOBAL FUNCTIONS
***********************/
lv_obj_t * dialpad_create(lv_obj_t * activity_obj)
{
    lv_dialpad_obj_ext_t * ext = NULL;
    lv_obj_t * btn = NULL;
    lv_obj_t * img = NULL;

    const char * dialpad_img[DIAL_PAD_NUM] = {
        ICON_DIALPAD_1,
        ICON_DIALPAD_2,
        ICON_DIALPAD_3,
        ICON_DIALPAD_4,
        ICON_DIALPAD_5,
        ICON_DIALPAD_6,
        ICON_DIALPAD_7,
        ICON_DIALPAD_8,
        ICON_DIALPAD_9,
        ICON_DIALPAD_BACK,
        ICON_DIALPAD_0,
        ICON_DIALPAD_DIAL,
    };

    //activity obj
    if(NULL == activity_obj) {
        lv_watch_activity_ext_t activity_ext;
        memset(&activity_ext, 0, sizeof(lv_watch_activity_ext_t));
        activity_ext.actId = ACT_ID_DIALPAD;
        activity_ext.create = dialpad_create;
        activity_ext.prepare_destory = dialpad_prepare_destory;
        activity_obj = lv_watch_creat_activity_obj(&activity_ext);
    }

    //watch obj
    lv_obj_t * obj = lv_watch_obj_create(activity_obj);

    if(setting_is_flying_mode()) {
        dialpad_note_create(obj);
        return obj;
    }

    lv_watch_obj_set_anim_mode(obj, LV_WATCH_ANIM_HOR_RIGHT_HIDE);
    ext = lv_obj_allocate_ext_attr(obj, sizeof(lv_dialpad_obj_ext_t));

    //phone number text area
    ext->ta = lv_textarea_create(obj, NULL);
    lv_textarea_set_cursor_hidden(ext->ta, true);
    lv_textarea_set_one_line(ext->ta, true);
    lv_textarea_set_max_length(ext->ta, 12);
    lv_textarea_set_text(ext->ta, "");
    lv_textarea_set_text_align(ext->ta, LV_LABEL_ALIGN_CENTER);
    lv_obj_set_size(ext->ta, DIAL_PAD_TA_W, DIAL_PAD_TA_H);
    lv_obj_align(ext->ta, NULL, LV_ALIGN_IN_TOP_MID, 0, 10);
    lv_obj_set_base_dir(ext->ta, LV_BIDI_DIR_LTR);
    lv_watch_obj_add_element(ext->ta);

    //circle
    ext->cont_circle = lv_cont_create(obj, NULL);
    lv_obj_set_size(ext->cont_circle, 50, 50);
    lv_obj_set_hidden(ext->cont_circle, true);

    lv_obj_set_style_local_bg_opa(ext->cont_circle, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_50);
    lv_obj_set_style_local_radius(ext->cont_circle, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, 100);
    lv_obj_set_style_local_border_width(ext->cont_circle, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, 0);

    //button container
    lv_obj_t * cont_btn = lv_cont_create(obj, NULL);
    lv_obj_set_size(cont_btn, DIAL_PAD_CONT_W, DIAL_PAD_CONT_H);
    lv_cont_set_layout(cont_btn, LV_LAYOUT_GRID);
    lv_obj_align(cont_btn, ext->ta, LV_ALIGN_OUT_BOTTOM_LEFT, 0, 5);
    lv_obj_set_click(cont_btn, false);
    lv_watch_obj_add_element(cont_btn);

    lv_obj_set_style_local_bg_opa(cont_btn, LV_GAUGE_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_0);
    lv_obj_set_style_local_pad_top(cont_btn, LV_GAUGE_PART_MAIN, LV_STATE_DEFAULT, 0);
    lv_obj_set_style_local_pad_bottom(cont_btn, LV_GAUGE_PART_MAIN, LV_STATE_DEFAULT, 0);
    lv_obj_set_style_local_pad_left(cont_btn, LV_GAUGE_PART_MAIN, LV_STATE_DEFAULT, 0);
    lv_obj_set_style_local_pad_right(cont_btn, LV_GAUGE_PART_MAIN, LV_STATE_DEFAULT, 0);
    lv_obj_set_style_local_pad_inner(cont_btn, LV_GAUGE_PART_MAIN, LV_STATE_DEFAULT, 0);
    lv_obj_set_style_local_border_width(cont_btn, LV_GAUGE_PART_MAIN, LV_STATE_DEFAULT, 0);

    //button
    for(int8_t i = 0; i < DIAL_PAD_NUM; i++) {
        btn = lv_btn_create(cont_btn, NULL);
        lv_obj_set_size(btn, (DIAL_PAD_CONT_W) / 3, (DIAL_PAD_CONT_H) / 4);
        lv_obj_add_style(btn, LV_OBJ_PART_MAIN, &lv_watch_style_transp);
        lv_obj_set_event_cb(btn, dialpad_btn_event_cb);

        img = lv_img_create(btn, NULL);
        lv_img_set_src(img, dialpad_img[i]);
        lv_obj_set_click(img, false);

        lv_watch_set_free_num(btn, i);
        lv_watch_obj_add_element(btn);
    }

    return obj;
}

void dialpad_create_event_cb(lv_obj_t * btn, lv_event_t e)
{
    (void)btn;

    if(LV_EVENT_CLICKED == e)
    {
        lv_watch_png_cache_all_free();
        dialpad_create(NULL);
    }
}

/**********************
 *  STATIC FUNCTIONS
 **********************/
static void dialpad_prepare_destory(lv_obj_t * activity_obj)
{
    lv_watch_png_cache_all_free();
}

static lv_dialpad_obj_ext_t * dialpad_get_ext(void)
{
    lv_obj_t * activity_obj = lv_watch_get_activity_obj(ACT_ID_DIALPAD);
    if(activity_obj == NULL) return NULL;

    lv_obj_t * watch_obj;
    lv_watch_get_child_obj(activity_obj, lv_watch_obj_signal, &watch_obj);
    if(watch_obj == NULL) return NULL;

    if(watch_obj) {
        lv_dialpad_obj_ext_t  * ext = lv_obj_get_ext_attr(watch_obj);
        return ext;

    }
    return NULL;
}

static void dialpad_note_create(lv_obj_t * obj)
{
    lv_obj_t * label = lv_label_create(obj, NULL);
    lv_obj_add_style(label, LV_OBJ_PART_MAIN, &lv_watch_font20);

    lv_label_set_align(label, LV_LABEL_ALIGN_CENTER);
    lv_obj_set_click(label, false);
    lv_label_set_long_mode(label, LV_LABEL_LONG_BREAK);
    lv_obj_set_width(label, lv_obj_get_width(obj) - 50);
    lv_label_set_text_id(label, WATCH_TEXT_ID_PLEASE_TURN_OFF_FLYING_MODE);
    lv_obj_align(label, obj, LV_ALIGN_CENTER, 0, 0);

    return;
}

static void dialpad_btn_event_cb(lv_obj_t * btn, lv_event_t e)
{
    switch(e) {
        case LV_EVENT_PRESSED:
            dialpad_btn_press_action(btn);
            break;

        case LV_EVENT_SHORT_CLICKED:
            dialpad_btn_short_click_action(btn);
            break;

        case LV_EVENT_LONG_PRESSED:
            dialpad_btn_long_press_action(btn);
            break;

        default:
            break;
    }
}

static lv_res_t dialpad_btn_press_action(lv_obj_t * btn)
{
    lv_obj_t * img = NULL;
    char num[2];
    lv_obj_user_data_t data = lv_obj_get_user_data(btn);
    uint32_t free_num = data.user_num;
    lv_dialpad_obj_ext_t * ext = dialpad_get_ext();

    switch(free_num) {
        case 0:
        case 1:
        case 2:
        case 3:
        case 4:
        case 5:
        case 7:
            snprintf(num, 2, "%d", free_num + 1);
            lv_textarea_add_text(ext->ta, num);
            break;

        case 9: //back
            img = lv_obj_get_child(btn, NULL);
            lv_img_set_src(img, ICON_DIALPAD_BACK_PR);
            break;

        case 11: //dial
            img = lv_obj_get_child(btn, NULL);
            lv_img_set_src(img, ICON_DIALPAD_DIAL_PR);
            break;

        default:
            break;
    }

    if((9 != free_num) && (11 != free_num)) { //not back or dial button
        //show circle
        lv_obj_set_hidden(ext->cont_circle, false);
        lv_obj_set_pos(ext->cont_circle, lv_obj_get_x(btn) + 19, lv_obj_get_y(btn) + 48);
    }

    return LV_RES_OK;
}

static lv_res_t dialpad_btn_long_press_action(lv_obj_t * btn)
{
    lv_obj_t * img = NULL;
    lv_obj_user_data_t data = lv_obj_get_user_data(btn);
    uint32_t free_num = data.user_num;
    lv_dialpad_obj_ext_t * ext = dialpad_get_ext();

    switch(free_num) {
        case 6:  //7*
            lv_textarea_add_text(ext->ta, "*");
            break;

        case 8:  //9#
            lv_textarea_add_text(ext->ta, "#");
            break;

        case 10: //0+
            lv_textarea_add_text(ext->ta, "+");
            break;

        case 9:  //back
            lv_textarea_set_text(ext->ta, "");

            img = lv_obj_get_child(btn, NULL);
            lv_img_set_src(img, ICON_DIALPAD_BACK);
            break;

        case 11: //dial
            img = lv_obj_get_child(btn, NULL);
            lv_img_set_src(img, ICON_DIALPAD_DIAL);
            break;

        default:
            break;
    }

    //hide circle
    lv_obj_set_hidden(ext->cont_circle, true);

    return LV_RES_OK;
}

static lv_res_t dialpad_btn_short_click_action(lv_obj_t * btn)
{
    lv_obj_t * img = NULL;
    char num[2];
    lv_obj_user_data_t data = lv_obj_get_user_data(btn);
    uint32_t free_num = data.user_num;
    lv_dialpad_obj_ext_t * ext = dialpad_get_ext();

    switch(free_num) {
        case 6:  //7*
        case 8:  //9#
            snprintf(num, 2, "%d", free_num + 1);
            lv_textarea_add_text(ext->ta, num);
            break;

        case 10: //0+
            lv_textarea_add_text(ext->ta, "0");
            break;

        case 9:  //back
            img = lv_obj_get_child(btn, NULL);
            lv_img_set_src(img, ICON_DIALPAD_BACK);

            lv_textarea_del_char(ext->ta);
            break;

        case 11: { //dial
            img = lv_obj_get_child(btn, NULL);
            lv_img_set_src(img, ICON_DIALPAD_DIAL);

            const char * number = lv_textarea_get_text(ext->ta);

            if(strlen(number) > 0) {
                char * number_mo = (char *)Hal_Mem_Alloc(strlen(number) + 1);
                strncpy(number_mo, number, strlen(number) + 1);

                phone_voice_call_req(number_mo);
            }
#if DIAL_PAD_TEST
            else {
/*
                //test MT call
                char number_mt[] = "1";
                int32_t index = 2;

                MMI_Modem_Call_Response_Clip_t * clip = NULL;
                clip = (MMI_Modem_Call_Response_Clip_t *)Hal_Mem_Alloc(sizeof(MMI_Modem_Call_Response_Clip_t));
                clip->number = (char *)Hal_Mem_Alloc(strlen(number_mt) + 1);
                strncpy(clip->number, number_mt, strlen(number_mt) + 1);

                watch_modem_call_response_ring(index);
                watch_modem_call_response_clip(index, clip);
*/
                const char *number_mt = "xu2";
                char *number;
                number = (char *)Hal_Mem_Alloc(strlen(number_mt) + 1);
                strncpy(number, number_mt, strlen(number_mt) + 1);

                watch_voip_incomingcall_response(number, 1);
            }
#endif
            break;
        }

        default:
            break;
    }

    //hide circle
    lv_obj_set_hidden(ext->cont_circle, true);

    return LV_RES_OK;
}

#endif /*USE_LV_WATCH_DIALPAD*/
